home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1992 June: ROMin Holiday / ADC Developer CD (1992-06) (''ROMin Holiday'')_iso / Developer Connection - 06-1992.iso / Development Platforms / Apple II / Essentials / Technical.Notes / IIGS / TN.IIGS.034 < prev    next >
Encoding:
Text File  |  1991-01-11  |  20.1 KB  |  457 lines  |  [TEXT/pdos]

  1. Apple II
  2. Technical Notes
  3. _____________________________________________________________________________
  4.                                                   Developer Technical Support
  5.  
  6. Apple IIGS
  7. #34:    Low-Level QuickDraw II Routines
  8.  
  9. Revised by:    Dave "Evad Snoyl" Lyons, Keith Rollin,
  10.                Steven Glass, Matt Deatherage & Eric Soldan       January 1991
  11. Written by:    Steven Glass                                          May 1988
  12.  
  13. This Technical Note describes the low-level routines which QuickDraw II uses
  14. to do much of the work in standard calls and mechanisms for calling these
  15. routines and accessing their data.
  16. Changed since November 1990:  Added a Note on custom bottleneck procedures and
  17. updated information on ShieldCursor and UnShieldCursor.
  18. _____________________________________________________________________________
  19.  
  20. QuickDraw II lets you customize low-level drawing operations by intercepting the
  21. "bottleneck procedures."  QuickDraw II calls an appropriate "bottleneck proc"
  22. every time it receives a call to draw an object, measure text, or deal with
  23. pictures.  For example, if an application calls PaintOval, QuickDraw II calls
  24. StdOval to do the real work, and if an application calls InvertRgn, QuickDraw II
  25. calls StdRgn to do the work.
  26.  
  27. Installing your own bottleneck procedures is a little bit tricky.  The QuickDraw
  28. II SetStdProcs call accepts a pointer to a 56-byte ($38 hex) record and fills
  29. that record with the addresses of the standard bottleneckprocedures of QuickDraw
  30. II.  You may modify this record by replacing those addresseswith the addresses
  31. of your own custom bottleneck procedures minus one.  (QuickDraw II pushes the
  32. address on the stack and executes an RTL to it, so the address in the record
  33. must point to the byte before the routine.)
  34.  
  35. Note:  A custom bottleneck procedure must not begin at the first byte of a
  36.        segment.  If it does, then the segment could load at the beginning of a
  37.        bank, and the address minus one would be in the wrong bank and RTL would
  38.        transfer control to the wrong location.  (See Apple IIgs Technical Note
  39.        #90, 65816 Tips and Pitfalls.)
  40.  
  41. After installing your own procedures, you use SetGrafProcs to tell QuickDraw II
  42. about them. The format of this call is as follows (taken from the E16.QUICKDRAW
  43. file in APW):
  44.  
  45.     ostdText      GEQU   $00 ; Pointer - QDProcs -
  46.     ostdLine      GEQU   $04 ; Pointer - QDProcs -
  47.     ostdRect      GEQU   $08 ; Pointer - QDProcs -
  48.     ostdRRect     GEQU   $0C ; Pointer - QDProcs -
  49.     ostdOval      GEQU   $10 ; Pointer - QDProcs -
  50.     ostdArc       GEQU   $14 ; Pointer - QDProcs -
  51.     ostdPoly      GEQU   $18 ; Pointer - QDProcs -
  52.     ostdRgn       GEQU   $1C ; Pointer - QDProcs -
  53.     ostdPixels    GEQU   $20 ; Pointer - QDProcs -
  54.     ostdComment   GEQU   $24 ; Pointer - QDProcs -
  55.     ostdTxMeas    GEQU   $28 ; Pointer - QDProcs -
  56.     ostdTxBnds    GEQU   $2C ; Pointer - QDProcs -
  57.     ostdGetPic    GEQU   $30 ; Pointer - QDProcs -
  58.     ostdPutPic    GEQU   $34 ; Pointer - QDProcs -
  59.  
  60. The following code fragment shows how you might replace the StdRect procedure
  61. with your own for a given window:
  62.  
  63.     pha                            ; open a test window
  64.     pha
  65.     PushLong #MWindData            ; standard setup for NewWindow
  66.     _NewWindow
  67.     _SetPort
  68.  
  69.     PushLong #MyProcs              ; get a record to modify
  70.     _SetStdProcs
  71.  
  72.     ldy #ostdRect                 ; get the low word of my rectangle routine
  73.     lda #myRect-1                 ; (minus one) and patch it in to the record
  74.     sta myProcs,y
  75.     lda #^myRect                   ; do the same for the high word
  76.     sta myProcs+2,y
  77.  
  78.     PushLong #MyProcs              ; install the procs
  79.     _SetGrafProcs
  80.  
  81. The interface to bottleneck procedures is different from the interface to other
  82. QuickDraw II routines; you do not make calls via the tool dispatcherand you pass
  83. most parameters on the direct page and in registers (rather than on the stack).
  84. To write your own bottleneck procedures, you have to know where the inputs to
  85. each call are kept and how to call the standard procedures from inside your own
  86. procedures.
  87.  
  88. The standard bottleneck procedures are accessed through vectors in bank $E0.
  89.  
  90.     StdText       $E01E04
  91.     StdLine       $E01E08
  92.     StdRect       $E01E0C
  93.     StdRRect      $E01E10
  94.     StdOval       $E01E14
  95.     StdArc        $E01E18
  96.     StdPoly       $E01E1C
  97.     StdRgn        $E01E20
  98.     StdPixels     $E01E24
  99.     StdComment    $E01E28
  100.     StdTxMeas     $E01E2C
  101.     StdTxBnds     $E01E30
  102.     StdGetPic     $E01E34
  103.     StdPutPic     $E01E38
  104.  
  105. When you call any of the standard procedures, the first direct page of QuickDraw
  106. II is active.  If you pass variables on any direct page other than the first
  107. (direct page locations greater than $FF), you can use a simpletrick to access
  108. them.  For example, to access TheFillPat ($10E) without changingthe direct page
  109. register:
  110.  
  111.     ldx    #$100                   ;offset to second DP
  112.     lda    >$OE,X                  ;gets "DP" location $10E
  113.  
  114. Certain locations on the direct page are always valid:
  115.  
  116.     PortRef      $24
  117.     MaxWidth     $20
  118.     MasterSCB    $08
  119.     UserID       $0A
  120.  
  121. DrawVerb is usually valid, but not always:
  122.  
  123.     DrawVerb     $38
  124.  
  125. Each of the bottleneck procedures uses the direct page differently.
  126.  
  127. QuickDraw II has an interesting bug relating to the standard conic bottleneck
  128. procedures.  If you replace any of the standard procedures with your own,
  129. QuickDraw II does not perform some of the setups it normally would before
  130. calling the standard conic procedures (stdRRect, stdOval, stdArc).  For example,
  131. if you replace StdRect with a custom rectangle routine, but leavethe other conic
  132. pointers alone (as shown in the code fragment above), QuickDrawII will not do
  133. all of the normal setups when calling the standard conicroutines. To deal with
  134. this bug of QuickDraw II, you must patch out the additional bottleneck
  135. procedures and set up those direct pages locations yourself, orthe results will
  136. not be what you expect.  The QuickDraw II direct-page variables you must
  137. initialize yourself in this instance are bulleted (o) below.
  138.  
  139. StdText
  140.     DrawVerb      $38    Describes the kind of text to draw.  There
  141.                          are three possible values:
  142.                              DrawCharVerb    0
  143.                              DrawTextVerb    1
  144.                              DrawCStrVerb    2
  145.     TextPtr       $DA    If the draw verb is DrawTextVerb or
  146.                          DrawCStrVerb, TextPtr points to the text
  147.                          buffer or C string to draw.
  148.     TextLength    $D8    If the draw verb is DrawTextVerb,
  149.                          TextLength contains the number of bytes in
  150.                          the text buffer.
  151.     CharToDraw    $D6    If the draw verb is DrawCharVerb,
  152.                          CharToDraw contains the character to draw.
  153.  
  154. StdLine
  155.     Y1            $A6    Starting Y value for the line to draw
  156.     X1            $A8    Starting X value for the line to draw
  157.     Y2            $AA    Ending Y value for the line to draw
  158.     X2            $AB    Ending X value for the line to draw
  159.     Rect2         $AE    Exactly the same thing as Y1, X1, Y2 and
  160.                          X2 in the top, left, bottom, and right of
  161.                          the rectangle
  162.  
  163. StdRect
  164.     DrawVerb      $38    One of the following five drawing verbs:
  165.                              Frame           0
  166.                              Paint           1
  167.                              Erase           2
  168.                              Invert          3
  169.                              Fill            4
  170.     Rect1         $A6    The rectangle to draw in standard form
  171.                          (top, left, bottom, right)
  172.     TheFillPat    $10E   The pattern to use for the rectangle if
  173.                          the verb is Fill
  174.  
  175. Note:    The QuickDraw II Auxiliary SpecialRect call does not use the
  176. rectangle bottleneck procedures.
  177.  
  178. StdRRect
  179.     DrawVerb      $38    One of the following five drawing verbs:
  180.                              Frame           0
  181.                              Paint           1
  182.                              Erase           2
  183.                              Invert          3
  184.                              Fill            4
  185.     Rect1         $A6    The boundary rectangle for the round
  186.                          rectangle
  187.     OvalRect      $295   A copy of the boundary rectangle for the
  188.                          round rectangle
  189.     OvalHeight    $208   The oval height for the rounded part of
  190.                          the round rectangle
  191.     OvalWidth     $20A   The oval width for the rounded part of the
  192.                          round rectangle
  193.     o ArcAngle    $D2    Must be 360
  194.     o StartAngle  $D4    Must be zero
  195.     TheFillPat    $10E   The pattern to use for the round rectangle
  196.                          if the verb is Fill
  197.  
  198. StdOval
  199.     DrawVerb      $38    One of the following five drawing verbs:
  200.                              Frame           0
  201.                              Paint           1
  202.                              Erase           2
  203.                              Invert          3
  204.                              Fill            4
  205.     Rect1         $A6    The boundary rectangle for the oval
  206.     OvalRect      $295   A copy of the boundary rectangle for the
  207.                          oval
  208.     o OvalHeight  $208   Must be the height of the oval
  209.     o OvalWidth   $20A   Must be the width of the oval
  210.     o ArcAngle    $D2    Must be 360
  211.     o StartAngle  $D4    Must be zero
  212.     TheFillPat    $10E   The pattern to use for the oval if the
  213.                          verb is Fill
  214.  
  215. StdArc
  216.     DrawVerb      $38    One of the following five drawing verbs:
  217.                              Frame           0
  218.                              Paint           1
  219.                              Erase           2
  220.                              Invert          3
  221.                              Fill            4
  222.     Rect1         $A6    The boundary rectangle for the arc
  223.     o OvalWidth   $20A   Must be the width of the boundary
  224.                          rectangle for the arc
  225.     ArcAngle      $D2    The number of degrees the arc will sweep
  226.     StartAngle    $D4    The starting position of the arc
  227.     TheFillPat    $10E   The pattern to use for the arc if the verb
  228.                          is Fill
  229.  
  230. StdPoly
  231.     DrawVerb      $38    One of the following five drawing verbs:
  232.                              Frame           0
  233.                              Paint           1
  234.                              Erase           2
  235.                              Invert          3
  236.                              Fill            4
  237.     RgnHandleA    $50    The handle to the polygon data structure
  238.     TheFillPat    $10E   The pattern to use for the polygon if the
  239.                          verb is Fill
  240.  
  241. StdRgn
  242.     DrawVerb      $38    One of the following five drawing verbs:
  243.                              Frame           0
  244.                              Paint           1
  245.                              Erase           2
  246.                              Invert          3
  247.                              Fill            4
  248.     RgnHandleC    $70    The handle to the region to draw
  249.     TheFillPat    $10E   The pattern to use for the region if the
  250.                          verb is Fill
  251.  
  252. StdPixels
  253.     SrcLocInfo    $CC    The LocInfo record for the source pixel
  254.                          map
  255.     DestLocInfo   $0C    The LocInfo record for the destination
  256.                          pixel map
  257.     SrcRect       $DC    The source rectangle for the operation in
  258.                          local coordinates for the source pixel map
  259.                          (as described in the source LocInfo
  260.                          record)
  261.     DestRect      $1C    The destination rectangle for the
  262.                          operation in local coordinates for the
  263.                          destination pixel map (as described in the
  264.                          destination  LocInfo record)
  265.     XferMode      $E4    The mode to use for data transfer
  266.     RgnHandleA    $50    The handle to the first region to which
  267.                          drawing is clipped (usually the ClipRgn
  268.                          from the GrafPort)  A NIL handle is not
  269.                          allowed.  To signify no clipping, pass a
  270.                          handle to the WideOpen region, which is
  271.                          defined as 10 bytes:
  272.  
  273.                          Length      $A       (word)
  274.                          -MaxInt    -$3FFF    (word)
  275.                          -MaxInt    -$3FFF    (word)
  276.                          +MaxInt    +$3FFF    (word)
  277.                          +MaxInt    +$3FFF    (word)
  278.  
  279.     RgnHandleB    $60    The handle to the second region to which
  280.                          drawing is clipped (usually the VisRgn
  281.                          from the GrafPort)  A NIL handle is not
  282.                          allowed.  To signify no clipping, pass a
  283.                          handle to the WideOpen region.
  284.     RgnHandleC    $70    The handle to the second region to which
  285.                          drawing is clipped (usually the mask
  286.                          region from the CopyPixels or the
  287.                          PaintPixels call)  A NIL handle is not
  288.                          allowed.  To signify no clipping, pass a
  289.                          handle to the WideOpen region.
  290.  
  291. StdComment
  292.     TheKind       $A6    The kind of input for the comment
  293.     TheSize       $A8    The number of bytes to put into the
  294.                          picture
  295.     TheHandle     $AA    The data to put into the picture
  296.  
  297. StdTxMeas
  298.     DrawVerb      $38    Describes the kind of text to draw.  There
  299.                          are three possible values:
  300.                              DrawCharVerb    0
  301.                              DrawTextVerb    1
  302.                              DrawCStrVerb    2
  303.     TextPtr       $DA    If the draw verb is DrawTextVerb or
  304.                          DrawCStrVerb, TextPtr points to the text
  305.                          buffer or C string to draw.
  306.     TextLength    $D8    If the draw verb is DrawTextVerb,
  307.                          TextLength contains the number of bytes in
  308.                          the text buffer.
  309.     CharToDraw    $D6    If the draw verb is DrawCharVerb,
  310.                          CharToDraw contains the character to
  311.                          measure.
  312.     TheWidth      $DE    The resulting width should be put here.
  313.  
  314. StdTxBnds
  315.     DrawVerb      $38    Describes the kind of text to draw.  There
  316.                          are three possible values:
  317.                              DrawCharVerb    0
  318.                              DrawTextVerb    1
  319.                              DrawCStrVerb    2
  320.     TextPtr       $DA    If the draw verb is DrawTextVerb or
  321.                          DrawCStrVerb, TextPtr points to the text
  322.                          buffer or C string to draw.
  323.     TextLength    $D8    If the draw verb is DrawTextVerb,
  324.                          TextLength contains the number of bytes in
  325.                          the text buffer.
  326.     CharToDraw    $D6    If the draw verb is DrawCharVerb,
  327.                          CharToDraw contains the character to draw.
  328.     RectPtr       $D2    Indicates the address to put the resulting
  329.                          rectangle.
  330.  
  331. StdGetPic
  332.     This call takes input on the stack rather than the direct page.  This is
  333.     the one standard bottleneck procedure which you call with the direct
  334.     page register set to something other than the direct page of QuickDraw
  335.     II; it is set to a part of the stack.
  336.  
  337.     Stack Diagram on Entrance to StdGetPic
  338.         Previous Contents
  339.         DataPtr              Pointer to destination buffer
  340.         Count                Integer (unsigned) (bytes to read)
  341.         RTL Address          3 bytes
  342.         -----------------    Top of Stack
  343.  
  344.     Stack Diagram just before exit from StdGetPic
  345.         Previous Contents
  346.         RTL Address          3 bytes
  347.         -----------------    Top of Stack
  348.  
  349. StdPutPic
  350.     This call takes input on the stack rather than the direct page; however,
  351.     unlike StdGetPic, the direct page for QuickDraw II is active when you
  352.     call this routine.
  353.  
  354.     Stack Diagram on Entrance to StdPutPic
  355.  
  356.         Previous Contents
  357.         DataPtr              Pointer to source buffer
  358.         Count                Integer (unsigned) (bytes to read)
  359.         RTL Address          3 bytes
  360.         -----------------    Top of Stack
  361.  
  362.     Stack Diagram just before exit from StdPutPic
  363.  
  364.         Previous Contents
  365.         RTL Address          3 bytes
  366.         -----------------    Top of Stack
  367.  
  368.  
  369. Dealing with the Cursor
  370.  
  371. The cursor can get in your way when you want to draw directly to the screen.
  372. QuickDraw II has two low-level routines which help you avoid this problem:
  373. ShieldCursor and UnshieldCursor.  ShieldCursor tells QuickDraw II to hide the
  374. cursor if it intersects the MinRect and to prevent the cursor from moving until
  375. you call UnshieldCursor.
  376.  
  377. There is a bug in ShieldCursor for System Disks 4.0 and earlier.  This bug is
  378. related to the routine ObscureCursor.  When the cursor is obscured, ShieldCursor
  379. does not prevent the cursor from moving; therefore, the user is able to move the
  380. cursor during a QuickDraw II operation, and this movementmay disturb the screen
  381. image.
  382.  
  383. Calls to ShieldCursor must be balanced by calls to UnshieldCursor.  You may not
  384. call ShieldCursor successively without calling UnshieldCursor after each call to
  385. ShieldCursor.  There is no error checking, so careless use of these routines
  386. will result in an unusable system.
  387.  
  388. MinRect is the smallest possible rectangle which encloses all the pixels that
  389. may be affected by a drawing call.  You keep MinRect on the direct page and
  390. usually calculate it by intersecting the rectangle of the object you are drawing
  391. with the BoundsRect, PortRect, boundary box of the VisRgn, and the boundary box
  392. of the ClipRgn.  You must set up MinRect yourself.
  393.  
  394. ShieldCursor also looks at two other fields on the direct page of QuickDraw II.
  395. ImageRef is a long word located at $0E.  If ImageRef does not point to $E12000
  396. or $012000, QuickDraw II assumes you are not drawing to the screen, so it does
  397. not have to shield the cursor.  BoundsRect is a rectangle located at $14, and
  398. QuickDraw II uses it to translate MinRect into global coordinates.  These values
  399. are generally correct, but under the following known circumstance,they are not
  400. and ShieldCursor will not function properly:
  401.  
  402. 1.    You have just drawn to an off-screen GrafPort with QuickDraw II.
  403. 2.    You switch to a GrafPort on the screen.
  404. 3.    You call ShieldCursor.
  405.  
  406. ImageRef and BoundsRect are not updated until QuickDraw II is actually committed
  407. to drawing, thus, these values are still for the off-screenGrafPort in this
  408. case, even though you switched to a GrafPort on the screen. Therefore, when you
  409. call ShieldCursor, you have to make sure that thesevalues are current.  (If
  410. these values are current, ShieldCursor will work correctly, no matter what the
  411. circumstances.)
  412.  
  413. You can find the location of the QuickDraw II direct page with the GetWAP call.
  414. For speed reasons, you may not want to make the GetWAP call for each
  415. ShieldCursor call.  You may wish to get the work area pointer value after
  416. starting QuickDraw II and store it for future reference.
  417.  
  418. Calling ShieldCursor:
  419. 1.  Set direct page for QuickDraw II.
  420. 2.  Save the existing values of MinRect, ImageRef, and BoundsRect.
  421. 3.  Set MinRect, ImageRef, and BoundsRect.
  422. 4.  Let QuickDraw II know you've changed the contents of its direct page by
  423.     clearing the "dirty" flags bits 14 to 0:
  424.  
  425.     DirtyFlags      equ     $EC
  426.  
  427.                     ldx     #$200           ;index to QD's third page of work
  428.     lda     DirtyFlags,x    ;space
  429.                     and     #$8000
  430.                     sta     DirtyFlags,x
  431.  
  432. 5.  JSL to ShieldCursor.
  433. 6.  Restore the previous values of MinRect, ImageRef, and BoundsRect.
  434.  
  435. Note:  Saving and restoring these values was not previously mentioned in this
  436.        Note and in most circumstances it is not necessary.  Saving and restoring
  437.        is now recommended.  In particular, if ShieldCursor is called inside a
  438.        QuickDraw II bottleneck procedure, the system can crash if you fail to
  439.        restore the contents of direct page.
  440.  
  441. Calling UnshieldCursor:
  442. 1.      Set direct page for QuickDraw II.
  443. 2.      JSL to UnshieldCursor.
  444.  
  445.  
  446. ShieldCursor      $E01E98
  447.     MinRect       $00
  448.     ImageRef      $0E
  449.     BoundsRect    $14
  450.  
  451. UnshieldCursor    $E01E9C
  452.  
  453.  
  454. Further Reference
  455. _____________________________________________________________________________
  456. o    Apple IIGS Toolbox Reference, Volume 2
  457.